--[[
	一个service，专门处理背包
]]

local filename = "knapsack.lua"

local skynet = require "skynet"
local cluster = require "skynet.cluster"
require "skynet.manager"

local filelog = require "filelog"
local timetool = require "timetool"
local tabletool = require "tabletool"
local redisdao = require "redisdao"
require "pubenum"

local json = require "cjson"
json.encode_sparse_array(true,1,1)

local routerbase = require "routerbase"

local Knapsack = routerbase:new()

--
--检测过期道具
--
local function check_props(proplist_json)
    local jsonstr = proplist_json
    local proplist = json.decode(proplist_json) or {}
    
    local now = timetool.get_time()
    local is_find = false
    local find_logoframe = false
    for k,item in pairs(proplist) do
        local kid = math.floor(item.id / 100)
        if kid == PropKind.HEADFRAME then
            if item.value and item.value > 0 and now > item.value then
                proplist[k] = nil
                is_find = true
            end
            if item.state == 1 then --装备中
                if not find_logoframe then
                    find_logoframe = true
                else
                    item.state = 2
                    is_find = true
                end
            end
        else
            if item.num and item.num <= 0 then
                proplist[k] = nil
                is_find = true
            end
        end
    end
    
    --重新编码,并更新数据库
    if is_find then
        jsonstr = json.encode(proplist) or "{}"
        cluster.call("datanode", ".router", "update_rk", rid, "rs_prop", 0, {prop_list_json = jsonstr})
    end

    return jsonstr
end

local function update_prop_usetimes(rid, propid, value)
    if value > 0 then return end
    local cur_time = timetool.get_time()
    local all_prop_usetimes = nil
    local key = tostring(rid) .. ":prop_usetimes"
    local result, data = redisdao.query_data(".gmmqredis", "get", key)
    if result and data then
        all_prop_usetimes = json.decode(data)
    else
        all_prop_usetimes =  all_prop_usetimes or {}
    end
    if all_prop_usetimes[tostring(propid)] == nil then
        all_prop_usetimes[tostring(propid)] = {
            last_use_time = cur_time,
            today_use_times = 0,
            total_use_times = 0,
        }
    end
    all_prop_usetimes[tostring(propid)].today_use_times = all_prop_usetimes[tostring(propid)].today_use_times - value
    all_prop_usetimes[tostring(propid)].total_use_times = all_prop_usetimes[tostring(propid)].total_use_times - value
    all_prop_usetimes[tostring(propid)].last_use_time = cur_time
    redisdao.query_data(".gmmqredis", "set", key, json.encode(all_prop_usetimes))
end


--获取背包数据
--propitem = {
--    id = 1,           道具id,3位 百位：1头像框 2会员卡 3互动表情 
--    value = 2,        消耗类道具：表示数量  时限类道具：表示过期时间,-1永不过期
--    state = 3,        使用状态 1装备中 2未装备
--}
--
function Knapsack.CMD.getknapsack(rid, is_check)
    local response = { }

    --从数据库获取背包道具
	local status,result = skynet.pcall(cluster.call, "datanode", ".router", "select_rk", rid, "rs_prop")
    if status and result and result[1] ~= 0 then
        response.prop_list_json = result[2][rid].prop_list_json
        --检测过期道具
        if is_check then
            response.prop_list_json = check_props(response.prop_list_json)
        end
    else
        return false
    end

    return response
end

--更新背包数据
--updateitem = {
--      id = 1,             道具id
--      value = 4,          道具数量变化值 +增加 -减少 时效性道具：有效期变化  消耗型道具：数量变化
--      state = 5,          道具状态变化值 1装备 2卸下
--}
--
function Knapsack.CMD.updateknapsack(rid, updatelist)
    if not rid or not updatelist then
        return false
    end

    local is_ok = true
    local bagdata = Knapsack.CMD.getknapsack(rid,false)
    local prop_list = json.decode(bagdata.prop_list_json or "{}") or {}
    for _,propitem in pairs(updatelist) do
        local id = tostring(propitem.id)
        local kid = math.floor(propitem.id / 100)
        if not prop_list[id] and propitem.value then --道具从无到有
            prop_list[id] = {id = propitem.id, value = 0 }
            if kid == PropKind.HEADFRAME then
                if propitem.value ~= -1 then
                    prop_list[id].value = timetool.get_time()
                else
                    prop_list[id].value = propitem.value
                end
            end
        end

        --道具不存在
        if not prop_list[id] then
            is_ok = false
            break
        end

        local item = prop_list[id]
        if kid == PropKind.HEADFRAME then      --头像框
            if propitem.value then
                if item.value >= 0 then    --更新到期时间
                    item.value = item.value + propitem.value
                    if item.value < 0 then
                        item.value = 0
                    end
                end
                if item.state == nil then
                    item.state = 2  --默认未装备
                end
            end
            if propitem.state then
                item.state = propitem.state
            end
            if item.value == 0 then
                prop_list[id] = nil
            end
        elseif kid == PropKind.INTERPROP or kid == PropKind.VIPCARD or kid == PropKind.GIFTSPACKAGE then  --会员卡 互动表情
            if item.value + propitem.value < 0  then
                filelog.sys_error("prop number not enough!", rid, id, item.value, propitem.value, item.value + propitem.value)
                is_ok = false
                break
            end
            item.value = item.value + propitem.value
            if kid == PropKind.GIFTSPACKAGE and propitem.value == -1 then
                update_prop_usetimes(rid, propitem.id, propitem.value)
            end
            if item.value <= 0 then
                prop_list[id] = nil
            end
        else
            is_ok = false
            break
        end
    end
    
    if not is_ok then
	    return false
    end
    local result = cluster.call("datanode", ".router", "update_rk", rid, "rs_prop", 0, {prop_list_json = json.encode(prop_list)})

    return true
end

--
--获得头像框id
--没有可使用头像框时返回0 否则返回头像框id
--
function Knapsack.CMD.getlogoframeid(rid, orilogoframe)
    local bagdata = Knapsack.CMD.getknapsack(rid, false)
    local prop_list = json.decode(bagdata.prop_list_json or "{}") or {} 
    local now = timetool.get_time()

    local logoframe = 0
    local updatelist = {}
    for _,item in pairs(prop_list) do
        local kid = math.floor(item.id / 100)
        if kid == PropKind.HEADFRAME then   --头像框类
            if item.state == 1 then
                if item.value > 0 and now > item.value then
                    local updateitem = { id = item.id }
                    updateitem.state = 2
                    updateitem.value = - item.value
                    table.insert(updatelist, updateitem)
                else
                    if orilogoframe ~= 0 then
                        if orilogoframe ~= item.id then
                            local updateitem = { id = item.id }
                            updateitem.state = 2
                            updateitem.value = 0
                            table.insert(updatelist, updateitem)
                        else
                            logoframe = item.id
                        end
                    else
                        local updateitem = { id = item.id }
                        updateitem.state = 2
                        updateitem.value = 0
                        table.insert(updatelist, updateitem)
                    end
                end
            end
        end
    end
    if logoframe == 0 then
        local prop_cfg = Knapsack.CMD.getpropconf(100)
        if prop_cfg then
            local updateitem = { id = prop_cfg.id }
            if prop_cfg.effecttime == -1 then
                updateitem.value = prop_cfg.effecttime
            end
            updateitem.state = 1
            logoframe = prop_cfg.id
            table.insert(updatelist, updateitem)
        end
    end
    Knapsack.CMD.updateknapsack(rid, updatelist)
    return logoframe
end

--
--获得道具配置
--
--道具配置项
--propconfitem = {
--    id = 1,           道具id
--    name = 2,         道具名字
--    effecttime = 3,   道具有效时间,单位：天  -1表示永久有效 针对时效型道具
--    descript = 4,     道具描述
--}
--
function Knapsack.CMD.getpropconf(prop_id)
    --从redis读取道具配置表
    local propconf_list = nil

    local result, data = redisdao.query_data(".gmmqredis", "get", "prop_conf_list")
    if result and data then
        propconf_list = json.decode(data)
    end
    if not propconf_list then
        return nil
    end

    --获得对应id道具的配置
    for k,item in pairs(propconf_list) do
        if item.id == prop_id then
            return item
        end
    end
   
    return nil
end

function Knapsack.CMD.getpropbyid(rid, propid)
    local prop_list_json = nil
    local status, result = skynet.pcall(cluster.call, "datanode", ".router", "select_rk", rid, "rs_prop")
    if status and result and result[1] ~= 0 then
        prop_list_json = result[2][rid].prop_list_json
    else
        return false
    end
    local prop_data = json.decode(prop_list_json)
    if prop_data[tostring(propid)] == nil then
        return false
    end
    local propdata = tabletool.deepcopy(prop_data[tostring(propid)])
    return propdata
end

function Knapsack.CMD.insert_test_data(rid)
    local propconf_list = nil
    local now = timetool.get_time()
    local result, data = redisdao.query_data(".gmmqredis", "get", "prop_conf_list")
    if result and data then
        propconf_list = json.decode(data)
    end
    --从数据库获取背包道具
    local prop_list_json = nil
	local status,result = skynet.pcall(cluster.call, "datanode", ".router", "select_rk", rid, "rs_prop")
    if status and result and result[1] ~= 0 then
        prop_list_json = result[2][rid].prop_list_json
        --检测过期道具
        if is_check then
            prop_list_json = check_props(response.prop_list_json)
        end
    end
    local proplist = nil 
    if prop_list_json == nil then
        proplist = {}
    else
        proplist = json.decode(prop_list_json)
    end

    for k, prop in pairs(propconf_list) do
        if proplist[prop.id] == nil then
            proplist[prop.id] = {
                id = 0,
                value = 0,
                state = 2,
            }
        end
        proplist[prop.id].id = prop.id
        local kid = math.floor(prop.id / 100)
        if kid == PropKind.HEADFRAME then   --头像框,增加有效时间
            proplist[prop.id].value = now + 7 * 1 * 24 * 3600
        elseif kid == PropKind.INTERPROP or kid == PropKind.VIPCARD then    --会员卡 互动表情，增加数量
            proplist[prop.id].value = 100
        end
    end
    local result = cluster.call("datanode", ".router", "update_rk", rid, "rs_prop", 0, {prop_list_json = json.encode(proplist)})
end

skynet.start(function()
	Knapsack:start()
end)
